import numpy as np
import pandas as pd
import json
from collections import defaultdict
import requests

def upload_to_jsonblob():
    try:
        with open("data/graph_data.json", "r", encoding="utf-8") as f:
            json_data = f.read()
        headers = {'Content-Type': 'application/json'}
        response = requests.post("https://jsonblob.com/api/jsonBlob", data=json_data, headers=headers)
        if response.status_code == 201:
            blob_url = response.headers["Location"]
            vosviewer_url = f"https://app.vosviewer.com/?json={blob_url}"
            print(f"上传成功！VOSviewer链接: {vosviewer_url}")
            return vosviewer_url
        else:
            print(f"上传失败，状态码: {response.status_code}")
            return None
    except Exception as e:
        print(f"上传异常: {e}")
        return None


class Clusterer:
    def __init__(self, num_nodes=300, num_relations=500):
        self.num_nodes = num_nodes
        self.num_relations = num_relations

    def get_json(self, terms_file):
        # 将 UploadedFile 对象转换为 DataFrame
        terms_data = []
        for line in terms_file:
            terms = line.decode('utf-8').strip()
            if terms:
                terms_data.append({'terms': terms})
        terms_df = pd.DataFrame(terms_data)
        
        dict_word_freq = defaultdict(int)
        dict_link_freq = defaultdict(int)
        for terms in terms_df['terms']:
            term_list = terms.split(';')
            for term in term_list:
                if term:
                    dict_word_freq[term] += 1

        sorted_terms = sorted(dict_word_freq.items(), key=lambda x: x[1], reverse=True)
        top_terms = [term for term, _ in sorted_terms[:self.num_nodes]]
        dict_word_freq = {term: dict_word_freq[term] for term in top_terms}

        for terms in terms_df['terms']:
            term_list = [k for k in terms.split(';') if k in dict_word_freq]
            for i in range(len(term_list)):
                for j in range(i + 1, len(term_list)):
                    dict_link_freq[(term_list[i], term_list[j])] += 1
        return dict_link_freq, dict_word_freq



    def create_graph_data(self, dict_link_freq, dict_word_freq):
        items = []
        for term, freq in dict_word_freq.items():
            items.append({
                "id": term,
                "label": term,
                "weights": {
                    "Documents": int(freq)
                }
            })

        links = []
        for (term1, term2), freq in sorted(dict_link_freq.items(), key=lambda x: x[1], reverse=True)[:self.num_relations]:
            links.append({
                "source_id": term1,
                "target_id": term2,
                "strength": float(freq)
            })

        return {
            "network": {
                "items": items,
                "links": links
            }
        }

    def process(self, terms_file):
        dict_link_freq, dict_word_freq = self.get_json(terms_file)
        graph_data = self.create_graph_data(dict_link_freq, dict_word_freq)

        # 保存文件
        with open("data/graph_data.json", "w", encoding="utf-8") as f:
            json.dump(graph_data, f, ensure_ascii=False, indent=2)

        # 上传获取URL
        vosviewer_url = upload_to_jsonblob()

        return vosviewer_url
